package com.angel.webapp.servlets;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.angel.architecture.exceptions.BusinessException;
import com.angel.architecture.flex.locator.ObjectLocator;
import com.angel.architecture.persistence.beans.ConfigurationParameter;
import com.angel.architecture.services.InitializerConfigurationService;
import com.angel.common.keyValue.KeyValueResult;
import com.angel.configuration.container.ConfigurationInitializerContainer;
import com.angel.webapp.keyValue.RequestKeyValueResult;

/**
 * @author William
 * @since 03/February/2009
 */
public abstract class BaseAngelServlet extends HttpServlet{
	private static final long serialVersionUID = 4403443581207701845L;
	
	private static final Logger LOGGER = Logger.getLogger(BaseAngelServlet.class);

	protected static final String REQUEST_PARAMETER_SEPARATOR = "=";
	
	/** Check request parameters to can make export process. If parameters necessaries are not present in the request, it throws
	 * a NonBusinessException.
	 *
	 * @param keyValueResult
	 * @see com.angel.arquitectura.exception.NonBusinessException
	 */
	protected abstract void doCheckParameters(KeyValueResult keyValueResult);
	
	/** Process current request. It can be by post or get method.
	 * 
	 * @param keyValueResult all request and cofiguration parameters.
	 * @param req current request to process.
	 * @param res response to current request.
	 */
	protected abstract void process(KeyValueResult keyValueResult, final HttpServletRequest req, final HttpServletResponse res);

	@Override
	protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
		this.doPost(req, res);
	}

	@Override
	protected void doPost(final HttpServletRequest request, final HttpServletResponse response) {
		try {
			LOGGER.info("Building key value result for http servlet request.");
			KeyValueResult keyValueResult = new RequestKeyValueResult(request);
	
			LOGGER.info("Initializing configuration parameters.");
			this.initializeConfiguration(keyValueResult);
			
			LOGGER.info("Checking configuration parameters.");
			this.doCheckParameters(keyValueResult);
	
			LOGGER.info("Processing post method with [" + keyValueResult.resultSize() + "] parameters.");
			this.process(keyValueResult, request, response);
		} catch (Throwable e) {
			throw new BusinessException("Se ha producido un error inesperado caused by: [" + e.getMessage() + "].", e);
		}
	}

	protected void initializeConfiguration(KeyValueResult keyValueResult) {
		String RE_INITIALIZE_CONFIGURATION_PARAMETERS = "RE_INITIALIZE_CONFIGURATION";
		boolean reInitialize = (keyValueResult.containsResultFor(RE_INITIALIZE_CONFIGURATION_PARAMETERS) ? (Boolean) keyValueResult.getResultFor(RE_INITIALIZE_CONFIGURATION_PARAMETERS): false);
		Collection<ConfigurationParameter> parameters;
		InitializerConfigurationService initializerConfigurationService = ObjectLocator.getBeanByName("initializerConfigurationService");
		boolean isInitialized = initializerConfigurationService.isInitialized();
		ConfigurationInitializerContainer initializersContainer = new ConfigurationInitializerContainer();
		LOGGER.info("Verify configuration parameters. Initialized: [" + isInitialized + "] - Reinitialize: [" + reInitialize + "].");
		if(!isInitialized){
			parameters = initializerConfigurationService.initializeConfiguration();
			LOGGER.info("Initializing configuration parameters [" + parameters.size() + " parameters].");
			initializersContainer.initInitializers();
			initializersContainer.configure(parameters);
		} else {
			if(reInitialize){
				parameters = initializerConfigurationService.reinitializeConfiguration();
				LOGGER.info("Re-initializing configuration parameters [" + parameters.size() + " parameters].");
				initializersContainer.initInitializers();
				initializersContainer.configure(parameters);	
			}
		}
	}
}